"""
基于FastMCP实现的MCP管理服务
与现有系统集成，提供标准化的MCP服务器管理、发现、监控和调用功能
"""

import asyncio
import logging
from typing import Dict, List, Any, Optional
from datetime import datetime
import aiohttp
from mcp.server.fastmcp import FastMCP

from src.config.settings import settings
from src.services.mcp_service import mcp_service_manager, MCPServiceError

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 创建FastMCP实例
mcp = FastMCP("MCP Manager")

# 存储注册的MCP服务器（与现有配置集成）
registered_servers: Dict[str, Dict[str, Any]] = {}


def _get_server_config(server_name: str) -> Dict[str, Any]:
    """
    获取服务器配置（与现有系统集成）
    
    Args:
        server_name: 服务器名称
        
    Returns:
        服务器配置
    """
    return settings.get_mcp_server_config(server_name)


@mcp.tool()
async def register_server(name: str, url: str, description: Optional[str] = None,
                         tags: Optional[List[str]] = None, api_key: Optional[str] = None) -> str:
    """
    注册MCP服务器
    
    Args:
        name: 服务器名称
        url: 服务器URL
        description: 服务器描述
        tags: 服务器标签列表
        api_key: 访问服务器的API密钥
        
    Returns:
        服务器ID
    """
    try:
        # 检查是否已存在同名或同URL的服务器
        existing_server_id = None
        for server_id, server_info in registered_servers.items():
            if server_info["name"] == name or server_info["url"] == url:
                existing_server_id = server_id
                break
        
        if existing_server_id:
            # 更新现有服务器
            server_id = existing_server_id
            registered_servers[server_id].update({
                "name": name,
                "url": url,
                "description": description,
                "tags": tags or [],
                "api_key": api_key,
                "updated_at": datetime.now().isoformat()
            })
            logger.info(f"服务器 {name} 信息已更新")
        else:
            # 创建新服务器
            server_id = f"srv_{len(registered_servers) + 1}"
            registered_servers[server_id] = {
                "id": server_id,
                "name": name,
                "url": url,
                "description": description,
                "tags": tags or [],
                "api_key": api_key,
                "status": "unknown",
                "created_at": datetime.now().isoformat(),
                "updated_at": datetime.now().isoformat()
            }
            logger.info(f"服务器 {name} 注册成功，ID: {server_id}")
        
        # 执行健康检查
        await check_health(server_id)
        
        return server_id
        
    except Exception as e:
        logger.error(f"注册服务器失败: {e}")
        raise Exception(f"注册服务器失败: {str(e)}")


@mcp.tool()
async def unregister_server(server_id: str) -> bool:
    """
    注销MCP服务器
    
    Args:
        server_id: 服务器ID
        
    Returns:
        是否成功注销
    """
    if server_id in registered_servers:
        server_name = registered_servers[server_id]["name"]
        del registered_servers[server_id]
        logger.info(f"服务器 {server_name} 注销成功")
        return True
    else:
        logger.warning(f"服务器 {server_id} 不存在")
        return False


@mcp.tool()
async def list_servers(status_filter: Optional[str] = None, tag_filter: Optional[str] = None) -> List[Dict[str, Any]]:
    """
    列出所有MCP服务器
    
    Args:
        status_filter: 状态过滤器 (healthy, unhealthy, error, unknown)
        tag_filter: 标签过滤器
        
    Returns:
        服务器列表
    """
    servers = []
    for server_id, server_info in registered_servers.items():
        # 应用状态过滤器
        if status_filter and server_info.get("status") != status_filter:
            continue
            
        # 应用标签过滤器
        if tag_filter and server_info.get("tags") and tag_filter not in server_info.get("tags", []):
            continue
            
        # 移除敏感信息
        server_copy = server_info.copy()
        server_copy.pop("api_key", None)
        servers.append(server_copy)
        
    # 同时包含现有系统配置的服务器
    for server_name in settings.MCP_SERVERS:
        # 检查是否已经在registered_servers中
        already_registered = False
        for server_info in registered_servers.values():
            if server_info.get("name") == server_name:
                already_registered = True
                break
        
        if not already_registered:
            config = _get_server_config(server_name)
            server_info = {
                "id": f"sys_{server_name}",
                "name": server_name,
                "url": config.get("url", ""),
                "description": f"系统配置的服务器: {server_name}",
                "tags": ["system"],
                "status": "unknown",
                "created_at": datetime.now().isoformat(),
                "updated_at": datetime.now().isoformat()
            }
            # 应用状态过滤器
            if status_filter and server_info.get("status") != status_filter:
                continue
                
            # 应用标签过滤器
            if tag_filter and server_info.get("tags") and tag_filter not in server_info.get("tags", []):
                continue
                
            # 移除敏感信息
            server_copy = server_info.copy()
            server_copy.pop("api_key", None)
            servers.append(server_copy)
        
    return servers


@mcp.tool()
async def get_server_info(server_id: str) -> Dict[str, Any]:
    """
    获取服务器详细信息
    
    Args:
        server_id: 服务器ID
        
    Returns:
        服务器信息
    """
    if server_id in registered_servers:
        # 移除敏感信息
        server_info = registered_servers[server_id].copy()
        server_info.pop("api_key", None)
        return server_info
    else:
        # 检查是否为系统配置的服务器
        for server_name in settings.MCP_SERVERS:
            sys_server_id = f"sys_{server_name}"
            if sys_server_id == server_id:
                config = _get_server_config(server_name)
                return {
                    "id": sys_server_id,
                    "name": server_name,
                    "url": config.get("url", ""),
                    "description": f"系统配置的服务器: {server_name}",
                    "tags": ["system"],
                    "status": "unknown",
                    "created_at": datetime.now().isoformat(),
                    "updated_at": datetime.now().isoformat()
                }
        
        raise Exception(f"服务器 {server_id} 不存在")


@mcp.tool()
async def check_health(server_id: Optional[str] = None) -> Dict[str, Any]:
    """
    检查服务器健康状态
    
    Args:
        server_id: 服务器ID，如果为None则检查所有服务器
        
    Returns:
        健康检查结果
    """
    if server_id:
        # 检查特定服务器
        server_info = None
        if server_id in registered_servers:
            server_info = registered_servers[server_id]
        else:
            # 检查是否为系统配置的服务器
            for server_name in settings.MCP_SERVERS:
                sys_server_id = f"sys_{server_name}"
                if sys_server_id == server_id:
                    config = _get_server_config(server_name)
                    server_info = {
                        "id": sys_server_id,
                        "name": server_name,
                        "url": config.get("url", ""),
                        "api_key": config.get("api_key", "")
                    }
                    break
        
        if not server_info:
            return {"status": "error", "message": "服务器不存在"}
            
        try:
            headers = {}
            if server_info.get("api_key"):
                headers['Authorization'] = f'Bearer {server_info["api_key"]}'
            
            async with aiohttp.ClientSession() as session:
                async with session.get(f'{server_info["url"]}/health', 
                                     headers=headers,
                                     timeout=aiohttp.ClientTimeout(total=5)) as response:
                    if response.status == 200:
                        health_data = await response.json()
                        result = {
                            "status": "healthy",
                            "message": "服务器健康",
                            "details": health_data
                        }
                    else:
                        result = {
                            "status": "unhealthy",
                            "message": f"HTTP {response.status}"
                        }
        except asyncio.TimeoutError:
            result = {
                "status": "error",
                "message": "健康检查超时"
            }
        except Exception as e:
            result = {
                "status": "error",
                "message": str(e)
            }
        
        # 更新服务器状态（仅对动态注册的服务器）
        if server_id in registered_servers:
            registered_servers[server_id]["status"] = result["status"]
            
        return {"server_id": server_id, **result}
    else:
        # 检查所有服务器
        results = {}
        
        # 检查动态注册的服务器
        for sid in registered_servers.keys():
            result = await check_health(sid)
            results[sid] = result
            
        # 检查系统配置的服务器
        for server_name in settings.MCP_SERVERS:
            sys_server_id = f"sys_{server_name}"
            # 检查是否已处理过
            if sys_server_id not in results:
                result = await check_health(sys_server_id)
                results[sys_server_id] = result
                
        return results


@mcp.tool()
async def discover_tools(server_id: str) -> List[Dict[str, Any]]:
    """
    发现服务器上的工具
    
    Args:
        server_id: 服务器ID
        
    Returns:
        工具列表
    """
    # 首先检查动态注册的服务器
    if server_id in registered_servers:
        server_info = registered_servers[server_id]
        server_name = server_info["name"]
    else:
        # 检查是否为系统配置的服务器
        server_name = None
        for name in settings.MCP_SERVERS:
            sys_server_id = f"sys_{name}"
            if sys_server_id == server_id:
                server_name = name
                break
        
        if not server_name:
            raise Exception(f"服务器 {server_id} 不存在")
    
    # 使用现有系统的服务管理器来发现工具
    try:
        # 调用list_tools工具获取工具列表
        result = mcp_service_manager.call_tool_sync(server_name, "list_tools", {})
        tools = result.get("tools", [])
        return tools
    except MCPServiceError as e:
        raise Exception(f"发现工具失败: {str(e)}")
    except Exception as e:
        raise Exception(f"发现工具失败: {str(e)}")


@mcp.tool()
async def invoke_tool(server_id: str, tool_name: str, parameters: Dict[str, Any]) -> Dict[str, Any]:
    """
    调用服务器上的工具
    
    Args:
        server_id: 服务器ID
        tool_name: 工具名称
        parameters: 工具参数
        
    Returns:
        调用结果
    """
    # 首先检查动态注册的服务器
    server_name = None
    if server_id in registered_servers:
        server_name = registered_servers[server_id]["name"]
    else:
        # 检查是否为系统配置的服务器
        for name in settings.MCP_SERVERS:
            sys_server_id = f"sys_{name}"
            if sys_server_id == server_id:
                server_name = name
                break
        
        if not server_name:
            raise Exception(f"服务器 {server_id} 不存在")
    
    # 使用现有系统的服务管理器来调用工具
    try:
        result = await mcp_service_manager.call_tool_async(server_name, tool_name, parameters)
        return result
    except MCPServiceError as e:
        raise Exception(f"工具调用失败: {str(e)}")
    except Exception as e:
        raise Exception(f"工具调用失败: {str(e)}")


async def main():
    """主函数"""
    from mcp.server.stdio import stdio_server
    
    logger.info("MCP管理服务已启动")
    logger.info("可用工具:")
    logger.info("- register_server: 注册MCP服务器")
    logger.info("- unregister_server: 注销MCP服务器")
    logger.info("- list_servers: 列出所有MCP服务器")
    logger.info("- get_server_info: 获取服务器信息")
    logger.info("- check_health: 检查服务器健康状态")
    logger.info("- discover_tools: 发现服务器工具")
    logger.info("- invoke_tool: 调用服务器工具")
    
    # 通过stdio运行MCP服务器
    async with stdio_server() as (read_stream, write_stream):
        mcp.run()


if __name__ == "__main__":
    asyncio.run(main())